﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.Logger;

namespace COFE.Core.Actions
{
    public interface IWorkScheduler
    {
        #region Public Properties

        /// <summary>
        /// Default retry count, everytime a work is failed, it will be enqueued again 
        /// </summary>
        int RetryCount { get; set; }

        /// <summary>
        /// Total ant require one thread to swi, does not count the thread used by the controller (WorkScheduler).        
        /// </summary>
        /// <exception cref="InvalidOperationException">Setting a value below 1.</exception>
        int TotalThread { get; set; }

        ///// <summary>
        ///// Lookup the SimpleWork in the queue based on the id.
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns>A work and it's retry count.</returns>
        //IWork this[Guid id] { get; }

        /// <summary>
        /// Each ant runs in separated thread to do the thread swi.
        /// </summary>
        IWorkSchedulerAnt[] WorkAnts { get; }

        /// <summary>
        /// All event are routed to this EventDispatcher, call SpawnListener to register to events.
        /// </summary>
        IEventDispatcher<WorkEventArgs> EventDispatcher { get; }

               

        #endregion

        #region Events

        #endregion

        #region Methods

        /// <summary>
        /// Return a list of enqueuedWorks (WorkState = Queued)
        /// </summary>
        /// <returns></returns>
        IEnumerable<ISchedule> GetEnqueuedSchedules(Func<ISchedule, bool> filter = null);

        /// <summary>
        /// Return a list of processing swi (WorkState = Working/Paused)
        /// </summary>
        /// <returns></returns>
        IEnumerable<ISchedule> GetProcessingSchedules(Func<ISchedule, bool> filter = null);


     

        ///// <summary>
        ///// Return a list of completed swi (WorkState = Error/Completed)
        ///// May appear multiple times if the same swi is enqueued multiple times.
        ///// </summary>
        ///// <returns></returns>
        //IEnumerable<IWork> GetCompletedWorks();

        


        /// <summary>
        /// Add a work to the thread queue, return whether success.        
        /// Fail if the SimpleWork is already started (WorkState = Queued/Working/Paused)        
        /// If success the WorkState will change to Queued.
        /// </summary>
        /// <param name="swi"></param>
        Guid Enqueue(WorkPriority priority, IWork work);

        Guid Enqueue(WorkPriority priority, TimeSpan interval, IWork work);

        Guid Enqueue(WorkPriority priority, DateTime utcTime, IWork work);


        /// <summary>
        /// Remove a work from a thread queue.
        /// If not executed yet, WorkState change from Queued to Initalized.
        /// Otherwise WorkState is not changed.
        /// </summary>
        /// <param name="workId"></param>
        /// <returns></returns>
        bool Dequeue(Guid scheduledWorkId);

        /// <summary>
        /// Complete all remaining swi and shut down the controller thread
        /// </summary>
        void Abort();

        /// <summary>
        /// If not autostart, you have to manually call this method to start the controller thread.
        /// </summary>
        void Start();

        void Pause();

        void Resume();

        ///// <summary>
        ///// Stop starting swi.
        ///// </summary>
        ///// <param name="includeProcessingWork">Pause the processing swi too.</param>
        //void Pause(bool includeProcessingWork = false);

        ///// <summary>
        ///// Resume the current thread queue, and all processing swi if paused.
        ///// </summary>
        //void Resume();

        #endregion
    }
}
